#include "head.h"     // 包含自定义头文件，通常用于声明类或函数
#include "games.h"    // 包含当前类的头文件，声明了games类的定义
#include "ui_games.h" // 包含UI文件生成的头文件，用于界面设计
#include <QPainter>   // 包含Qt绘图模块，用于绘制图形
#include <QTimer>     // 包含Qt定时器模块，用于定时触发事件
#include <QDialog>
#include <QMenu>
#include <QAction>
#include <QFile>
#include <QMouseEvent>
#include <QColorDialog>
#include <QFileDialog>


/**
 * @brief games类的构造函数。
 * @param parent 父窗口指针，通常用于管理窗口的父子关系。
 * 初始化UI界面，并设置初始角度为0。
 */
games::games(QWidget *parent) : QDialog(parent), ui(new Ui::games), angle(0)
{
    ui->setupUi(this); // 初始化UI界面
    resize(QT_WIDTH, QT_HEIGHT);
    // 初始化定时器，用于旋转太极图
    // QTimer *timer = new QTimer(this);                            // 创建一个定时器对象
    // connect(timer, &QTimer::timeout, this, &games::updateAngle); // 连接定时器的超时信号到updateAngle槽函数
    // timer->start(50);                                            // 启动定时器，每50毫秒触发一次超时信号
}
/**
 * 颜色选择器
 */

void games::colorSelect()
{
    QColorDialog *pColorDlg = new QColorDialog;
    pColorDlg->setCurrentColor(QColor(255, 0, 0));
    pColorDlg->exec();

    QColor color = pColorDlg->currentColor();
    qDebug() << "当前颜色" << color.red() << "," << color.green() << "," << color.blue() << endl;
}
/**
 * 文件选择器
 */
void games::fileSelect()
{
    QString fileName = QFileDialog::getOpenFileName(this, "选择文件", "./", "All Files (*)");
    qDebug() << "选中文件" << fileName << endl;
}
/**
 * 另存为文件
 */
void games::saveFile()
{
    QString fileName = QFileDialog::getSaveFileName(this, "另存为", "./1.txt", "All Files (*)");
    qDebug() << "保存" << fileName << endl;
}
/**
 * 创建文件并且写入
*/
void games::createFile()
{
    
}
/**
 * @brief games类的析构函数。
 * 释放UI界面的内存。
 */
games::~games()
{
    delete ui; // 删除UI对象，释放内存
}

/**
 * @brief 重写paintEvent函数，用于绘制图形。
 * @param event 绘图事件对象，包含绘图相关的信息。
 * 该函数在窗口需要重绘时自动调用，用于绘制太极图。
 */
void games::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);                               // 忽略未使用的event参数，避免编译器警告
    QPainter painter(this);                        // 创建一个QPainter对象，用于在当前窗口上绘图
    painter.setRenderHint(QPainter::Antialiasing); // 设置抗锯齿，使图形边缘更平滑

    // 设置画笔（QPen）
    QPen pen;                    // 创建一个QPen对象，用于设置画笔属性
    pen.setStyle(Qt::SolidLine); // 设置画笔样式为实线
    pen.setWidth(5);             // 设置画笔线宽为5像素
    painter.setPen(pen);         // 将画笔应用到QPainter对象

    // 绘制太极图
    int radius = 100;                                     // 定义太极图的半径
    QRect rect(-radius, -radius, 2 * radius, 2 * radius); // 定义太极图的外接矩形

    painter.translate(580, 400); // 将坐标系原点移动到指定位置
    painter.rotate(angle);                        // 旋转坐标系，实现太极图的旋转效果

    // 绘制外圆
    painter.drawEllipse(rect); // 绘制太极图的外圆

    // 绘制小圈1
    painter.drawEllipse(QRect(25, -50, 20, 20)); // 在太极图的上半部分绘制一个小圆

    // 绘制小圈2
    painter.drawEllipse(QRect(-25, 50, 20, 20)); // 在太极图的下半部分绘制另一个小圆

    // 绘制中间的S形曲线
    QPainterPath path;       // 创建一个QPainterPath对象，用于定义路径
    path.moveTo(0, -radius); // 将路径的起点移动到太极图的上顶点
    // 使用三次贝塞尔曲线绘制S形曲线
    path.cubicTo(-radius / 2, -radius / 2, radius / 2, radius / 2, 0, radius); // 定义控制点和终点
    painter.drawPath(path);                                                    // 绘制路径
}

/**
 * @brief 更新旋转角度。
 * 该函数由定时器触发，每次调用时增加角度，并触发窗口重绘。
 */
void games::updateAngle()
{
    angle += 5;       // 每次调用增加5度
    if (angle >= 360) // 如果角度超过360度，则重置为0度
        angle -= 360;
    update(); // 触发窗口重绘
}

/**
 * @brief 处理窗口移动的函数。
 * @param _this 指向当前games对象的指针。
 * 生成随机坐标，确保移动距离大于300像素，并移动窗口到新位置。
 */
void handlerMover(games *_this)
{
    while (1)
    {
        int x2 = rand() % 500; // 生成0到499的随机x坐标
        int y2 = rand() % 500; // 生成0到499的随机y坐标
        // 如果随机坐标绝对值减去原坐标绝对值大于300
        if (abs(abs(x2) - abs(_this->x)) > 400 && abs(abs(y2) - abs(_this->y)) > 300)
        {
            _this->x = x2; // 更新x坐标
            _this->y = y2; // 更新y坐标
            break;         // 退出循环
        }
    }
    qDebug() << "随机坐标为" << _this->x << "-" << _this->y << endl; // 输出随机坐标
    // 窗口随机平滑移动
    _this->move(_this->x, _this->y); // 移动窗口到新位置
}

/**
 * @brief 鼠标进入窗口事件。
 * @param event 鼠标事件对象，包含鼠标事件相关的信息。
 * 当鼠标进入窗口时，调用handlerMover函数移动窗口。
 */
void games::enterEvent(QEvent *event)
{
    qDebug() << "鼠标进入窗口" << endl; // 输出调试信息
    // handlerMover(this);                // 调用handlerMover函数移动窗口
}

/**
 * @brief 窗口关闭事件。
 * @param event 关闭事件对象，包含关闭事件相关的信息。
 * 当用户尝试关闭窗口时，弹出确认对话框，根据用户选择决定是否关闭窗口。
 */
void games::closeEvent(QCloseEvent *event)
{
    QMessageBox::StandardButton ret = QMessageBox::question(
        this,
        "温馨提示",
        "你真的要关掉么",
        QMessageBox::Yes | QMessageBox::No); // 弹出确认对话框

    if (QMessageBox::Yes == ret) // 如果用户选择“是”
    {
        event->accept(); // 接受关闭事件（注释掉，实际不关闭窗口）
        // event->ignore(); // 忽略关闭事件
    }
    else // 如果用户选择“否”
    {
        event->ignore(); // 忽略关闭事件
    }
}

/**
 * @brief 处理鼠标释放事件的函数。
 *
 * 该函数在鼠标按钮释放时被调用，主要用于处理右键点击事件。当检测到右键点击时，
 * 会创建一个上下文菜单，并添加三个菜单项。每个菜单项被点击时，会在调试输出中打印相应的信息。
 *
 * @param event 鼠标事件对象，包含鼠标事件的相关信息，如按钮类型、位置等。
 */
void games::mouseReleaseEvent(QMouseEvent *event)
{
    // 创建一个新的上下文菜单
    QMenu *pMenu = new QMenu;

    // 添加第一个菜单项，并连接其触发信号到Lambda表达式
    QAction *pAction1 = pMenu->addAction("haha");
    connect(pAction1, &QAction::triggered, [=]()
            { qDebug() << "右键菜单第一项" << endl; });

    // 添加第二个菜单项，并连接其触发信号到Lambda表达式
    QAction *pAction2 = pMenu->addAction("hehe");
    connect(pAction2, &QAction::triggered, [=]()
            { qDebug() << "右键菜单第二项" << endl; });

    // 添加第三个菜单项，并连接其触发信号到Lambda表达式
    QAction *pAction3 = pMenu->addAction("xixi");
    connect(pAction3, &QAction::triggered, [=]()
            { qDebug() << "右键菜单第三项" << endl; });

    // 判断是否为右键点击事件
    if (Qt::RightButton == event->button())
    {
        // 以模态方式显示上下文菜单，菜单位置为当前光标位置
        pMenu->exec(QCursor().pos());
    }
}
void games::on_pushButton_clicked()
{
    colorSelect();
}

void games::on_pushButton_2_clicked()
{
    fileSelect();
}

void games::on_pushButton_3_clicked()
{
    saveFile();
}

void games::on_lineEdit_textChanged(const QString &arg1)
{
    fileName = arg1;
    qDebug() << arg1 << endl;
    qDebug() << fileName << endl;
}

void games::on_pushButton_4_clicked()
{
    QFile file(fileName);
    if(file.open(QIODevice::ReadOnly)){
        qint64 ret = file.write("hello world");
        if(ret == -1){
            qDebug() << "写入失败" << endl;
        }else{
            qDebug() << "写入成功" << endl;
        }
    }else{
        qDebug() << "打开失败" << endl;
    }
    file.close();
}
